<template>
  <PageWrapper>
    <!-- 笔记 -->
    <CollapseContainer class="mt-5" title="Pinia">
      <markdown-viewer :value="getDoc()" />
    </CollapseContainer>

    <CollapseContainer class="mt-5" title="Pinia 基础">
      <Father />
      <template #action>
        <Icon
          icon="ant-design:code-outlined"
          class="mr-1"
          :size="26"
          @click="openSource('Pinia 基本使用', getSource())"
        />
      </template>
    </CollapseContainer>

    <!-- 源码组件 -->
    <SourceDrawer ref="sourceDrawer" />
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { CollapseContainer } from '@/components/Container';
  import { MarkdownViewer } from '@/components/Markdown';
  import { PageWrapper } from '@/components/Page';
  import SourceDrawer from '@/learn/SourceDrawer.vue';
  import { Icon } from '@/components/Icon';
  // 需要引入 computed 方法
  import { ref } from 'vue';
  import Father from './comps/Father.vue';

  // 定义子组件引用
  let sourceDrawer = ref<any>(null);
  function openSource(title: string, content: string) {
    sourceDrawer.value.open({ title, content, width: '60%' });
  }
</script>

<script lang="ts">
  function getDoc() {
    return `
* 修改数据:
    * 直接修改 state 值: 因为是响应式对象，所以可以
    * 通过 action 修改: 调用自定义 action 方法来修改
    * 通过内置变量 $patch 来修改
* 监听: 通过 $subscribe 订阅数据，可以实现监听 state 变更
* 重置: 内置 $reset 方法，可以实现 state 重置。也可以再 store 文件中重写 reset 方法

`;
  }

  function getSource() {
    return `
父组件和子组件代码相同，子组件将 Child 删除即可，否则进入无限循环了。

\`\`\`html
<template>
  <div class="mt-5 bg-gray-300 p-5" title="父组件" :can-expan="false">
    <h3>父组件</h3>
    <ul>
      <li>id:{{ id }} </li>
      <li>familyName:{{ familyName }} <Button @click="changeFamilyName">ref修改</Button></li>
      <li>name:{{ name }} <Button @click="changeName">action修改</Button></li>
      <li>fullName:{{ getFullName }} <Button @click="changeFullName">$path修改</Button></li>
      <li><Button @click="doReset">$reset重置</Button></li>
    </ul>

    <!-- 子组件: 子组件删除即可-->
    <Child />
  </div>
</template>

\<script lang="ts" setup\>
  import Child from './Child.vue';
  import { storeToRefs } from 'pinia';
  import { Button } from '@/components/Button';

  import { useMessage } from '@/hooks/web/useMessage';

  // 1.引入自定义 store 组件
  import { useTestStore } from '@/store/modules/testTraditional';

  const { createMessage } = useMessage();

  // 2.调用 store，获取暴露的对象: {states, getters, acctions}
  const testStore = useTestStore();

  // 3.解构 state 数据, 使用 pinia 的 storeToRefs 而非 vue 的 toRefs
  const { id, familyName, name, getFullName } = storeToRefs(testStore);

  // 修改方式一: 引用对象直接修改
  function changeFamilyName() {
    // 直接操作引用对象修改
    familyName.value += '~';
  }

  // 修改方式二: 使用自定义 action 方式修改
  function changeName() {
    // 调用 store 的 action 修改
    testStore.updateName(name.value + '*-');
  }

  // 修改方式三: 使用内置变量 $patch 修改, 原子性
  function changeFullName() {
    testStore.$patch({
      familyName: 'li',
      name: 'si',
    });
  }

  function doReset() {
    testStore.$reset();
  }

  // 监听 state 状态变化
  testStore.$subscribe((mutation, state) => {
    console.log('mutation', mutation);
    console.log('state', state);

    createMessage.error('父组件: 变更id:' + mutation.storeId + ', 变更内容:' + JSON.stringify(state));
  });
\</script\>
\`\`\`
`;
  }
</script>

<style lang="less" scoped>
  button {
    margin-left: 5px;
  }
</style>
